package 两数之和;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 两数之和
 * 给定一个整数数组nums，从数组中找出两个数满足相加之和等于目标数target。
 * <p>
 * 假设每个输入只对应唯一的答案，而且不可以重复使用相同的元素。
 * <p>
 * 返回两数的下标值，以数组形式返回。
 */
public class Solution {
    public static void main(String[] args) {


        int[] nums = new int[]{1, 2, 3, 4, 6};

        int[] index = bf(nums, 6);
        System.out.println("res = " + Arrays.toString(index));

        index = map(nums, 6);
        System.out.println("res = " + Arrays.toString(index));

        index = twoSearch(nums, 6);
        System.out.println("res = " + Arrays.toString(index));

        index = twoPoint(nums, 6);
        System.out.println("res = " + Arrays.toString(index));
    }

    /**
     * map法
     */
    public static int[] map(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>(nums.length);
        for (int i = 0; i < nums.length; i++) {
            int curr = nums[i];
            int y = target - curr;
            if (map.containsKey(y)) {
                return new int[]{map.get(y), i};
            }

            map.put(curr, i);
        }
        return new int[]{};
    }

    /**
     * 二分法(有序数组)
     */
    public static int[] twoSearch(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            int l = i + 1, r = nums.length;
            while (l <= r) {
                int mid = l + (r - l) / 2;
                int sum = nums[mid] + nums[i];
                if (target == sum) {
                    return new int[]{i, mid};
                } else if (target > sum) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return null;
    }

    /**
     * 双指针法(有序数组)
     */
    public static int[] twoPoint(int[] nums, int target) {
        int l = 0, r = nums.length - 1;

        while (l < r) {
            int sum = nums[l] + nums[r];
            if (target == sum) {
                return new int[]{l, r};
            }
            if (target > sum) {
                l++;
            } else {
                r--;
            }
        }
        return new int[]{};
    }

    /**
     * 暴力算法 O(n*n)
     */
    public static int[] bf(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[]{-1, -1};
    }


}
